package com.bn.commerce.pricing;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import atg.commerce.order.CommerceItem;
import atg.commerce.order.Order;
import atg.commerce.order.ShippingGroup;
import atg.commerce.order.ShippingGroupCommerceItemRelationship;
import atg.commerce.pricing.PricingException;
import atg.commerce.pricing.ShippingCalculatorImpl;
import atg.commerce.pricing.ShippingPriceInfo;
import atg.multisite.Site;
import atg.multisite.SiteContextManager;
import atg.repository.RepositoryItem;

import com.bn.commerce.order.BNPropertyNameConstants;

public class BNShippingCalculatorImpl extends ShippingCalculatorImpl{

	private boolean rangeShipPriceEnabled;

	protected double getAmount(Order pOrder, ShippingPriceInfo pPriceQuote, ShippingGroup pShippingGroup, RepositoryItem pPricingModel, Locale pLocale, RepositoryItem pProfile, Map pExtraParameters)
			throws PricingException {
		double price = pPriceQuote.getAmount();

		if(rangeShipPriceEnabled){
			price = getProductWeight(pShippingGroup,price);
		} else {
			List<RepositoryItem> shippingMethods = new ArrayList<RepositoryItem>();
			Site site = SiteContextManager.getCurrentSite();
			if (null != site) {
				shippingMethods = (List<RepositoryItem>) site.getPropertyValue(BNPropertyNameConstants.SITE_SHIPPING_METHODS);
				 for(RepositoryItem shipMethodItem : shippingMethods){
					Object shippingMethod =   shipMethodItem.getPropertyValue(BNPropertyNameConstants.SITE_SHIPPING_METHOD);
					if(pShippingGroup.getShippingMethod() != null){
						if(pShippingGroup.getShippingMethod().equals(shippingMethod)){
							Double priceObj = (Double)shipMethodItem.getPropertyValue(BNPropertyNameConstants.SITE_SHIPPING_AMOUNT);
							if (priceObj != null) {
								price = priceObj;
							}
						}
					}
				 }
			}
		}
		return price;
	}




	private Double getProductWeight(ShippingGroup pShippingGroup,Double price) {
		RepositoryItem product = null;
		Double amount = 0.0;
		if(pShippingGroup != null){
			List<ShippingGroupCommerceItemRelationship> commerceItems = pShippingGroup.getCommerceItemRelationships();
			for(ShippingGroupCommerceItemRelationship  shippingGroupCommerceItems: commerceItems){
				CommerceItem item = shippingGroupCommerceItems.getCommerceItem();
				if(item.getAuxiliaryData() != null){
					product = (RepositoryItem) item.getAuxiliaryData().getProductRef();
					 if(product != null){
						 Double producTweight = (Double)product.getPropertyValue("productWeight");
						 if(producTweight != null){
							 List<BNShippingRangeBean> shippingRanges =  populateShippingRange(pShippingGroup);
							 amount += getAmountOnRange(producTweight,shippingRanges)* item.getQuantity();
						 }
					 }
				}
			}
		}
		return amount;
	}

	private Double getAmountOnRange(Double producTweight,
			List<BNShippingRangeBean> shippingRanges) {
		Double price = 0.0;
		for(BNShippingRangeBean range : shippingRanges){
			Double minRange = range.getMinRange();
			Double maxRange = range.getMaxRange();
			if((minRange <= producTweight) && (producTweight > maxRange)){
				Double shippingPrice = range.getAmount();
				if (shippingPrice != null) {
					price = price + shippingPrice;
					System.out.println("range"+range);
				}
			}
		}
		return price;

	}

	private List<BNShippingRangeBean> populateShippingRange(ShippingGroup pShippingGroup) {
		List<RepositoryItem> shippingMethods = new ArrayList<RepositoryItem>();
		List<RepositoryItem> shippingRangeList = new ArrayList<RepositoryItem>();
		List<BNShippingRangeBean> shippingRanges = new ArrayList<BNShippingRangeBean>();
		Site site = SiteContextManager.getCurrentSite();
		if (null != site) {
			shippingMethods = (List<RepositoryItem>) site.getPropertyValue(BNPropertyNameConstants.SITE_SHIPPING_METHODS);
			 for(RepositoryItem shipMethodItem : shippingMethods){
				 if(shipMethodItem.getPropertyValue(BNPropertyNameConstants.SITE_SHIPPING_METHOD).equals(pShippingGroup.getShippingMethod())){
					 shippingRangeList =  (List<RepositoryItem>) shipMethodItem.getPropertyValue(BNPropertyNameConstants.SITE_SHIPPING_RANGE);
					 for(RepositoryItem shippingRange : shippingRangeList){
						 BNShippingRangeBean bean = new BNShippingRangeBean();
						 Double minRange =  (Double)shippingRange.getPropertyValue(BNPropertyNameConstants.SITE_SHIPPING_MINRANGE);
						 Double maxRange =  (Double)shippingRange.getPropertyValue(BNPropertyNameConstants.SITE_SHIPPING_MAXRANGE);
						 Double amount =  (Double)shippingRange.getPropertyValue(BNPropertyNameConstants.SITE_SHIPPING_RANGE_AMOUNT);
						 bean.setMinRange(minRange);
						 bean.setMaxRange(maxRange);
						 bean.setAmount(amount);
						 shippingRanges.add(bean);
					 }
				 }
			 }
		}
		return shippingRanges;
	}




	public List<RepositoryItem> getAvailableMethodDetails(List<Map<String, Object>> shippingDetails, ShippingGroup pShippingGroup, RepositoryItem pPricingModel, Locale pLocale, RepositoryItem pProfile,
		Map pExtraParameters) throws PricingException {
		List<RepositoryItem> shippingMethods = new ArrayList<RepositoryItem>();
		Site site = SiteContextManager.getCurrentSite();
		if (null != site) {
			 shippingMethods = (List<RepositoryItem>) site.getPropertyValue(BNPropertyNameConstants.SITE_SHIPPING_METHODS);
		}
		return shippingMethods;

	}

	@Override
	protected boolean performPricing(ShippingGroup arg0) {
		/* To compare selected value with property file (OOTB has three property file to compare, we have created only one for that reason sending true otherwise it wont call)*/
		return true;
	}




	public boolean isRangeShipPriceEnabled() {
		return rangeShipPriceEnabled;
	}




	public void setRangeShipPriceEnabled(boolean rangeShipPriceEnabled) {
		this.rangeShipPriceEnabled = rangeShipPriceEnabled;
	}
}
